﻿using System.Linq;
using Daemon.Common;
using Daemon.Common.Helpers;
using Daemon.Infrustructure.EF;
using Daemon.Repository.EF.Enums;
using Daemon.Repository.Contract;
using Daemon.Model;
using System;
using System.Linq.Expressions;
using System.Collections.Generic;

namespace Daemon.Repository.EF
{
	public class TakeAwayUserAddressRepository : Repository<TakeAwayUserAddress>, ITakeAwayUserAddressRepository
	{
		protected override Expression<Func<TakeAwayUserAddress, int>> PrimaryKeyExpression => r => r.Id;

		public TakeAwayUserAddressRepository(ApiDBContent context) : base(context)
		{
		}

		public IEnumerable<TakeAwayUserAddress> GetUserAddressByUserId(int? shopId, int userId)
		{
			var userAddresses = Context.TakeAwayUserAddress.Where(r => r.UserId == userId).ToList();
			if (!shopId.HasValue)
			{
				return userAddresses;
			}

			var shopInfo = Context.TakeAwayShopCoordinate.First(r => r.ShopId == shopId);
			var maxDistance = Context.TakeAwayMoneySetting.Max(r => r.MaxDistance);
			foreach (var address in userAddresses)
			{
				if (shopId.HasValue)
				{
					var distance = GeoHelper.CalculateDistance((double)address.Lat, (double)address.Lng, Convert.ToDouble(shopInfo.Lat), Convert.ToDouble(shopInfo.Lng));
					address.IsEnable = distance <= maxDistance;
				}
				else
				{
					address.IsEnable = true;
				}
			}

			return userAddresses;
		}

		protected override IEnumerable<TakeAwayUserAddress> IncludeRelationships(IEnumerable<TakeAwayUserAddress> entities, ApiDBContent db)
		{
			GetUserInfo(entities);

			return base.IncludeRelationships(entities, db);
		}

		private void GetUserInfo(IEnumerable<TakeAwayUserAddress> entities)
		{
			if (!RouteParameterHelper.CheckRouteParameter(RelationshipNames, TakeAwayUserAddressRelationshipEnum.UserInfo))
			{
				return;
			}

			var userIds = entities.Select(r => r.UserId).ToList();
			var dicUser = Context.TakeAwayUser.Where(r => userIds.Contains(r.Id)).ToDictionary(r => r.Id, r => r);

			foreach (var entity in entities)
			{
				if (dicUser.TryGetValue(entity.UserId, out TakeAwayUser user))
				{
					entity.TakeAwayUser = user;
				}
			}
		}
	}
}
